<template>
  <a-modal
    class="image-cropper"
    v-model:visible="visible"
    title="编辑图片"
    :footer="false"
    @cancel="closeModal"
  >
    <!--图片组件-->
    <vue-cropper
      ref="cropperRef"
      :img="imageUrl"
      output-type="png"
      :info="true"
      :can-move-box="true"
      :fixed-box="false"
      :auto-crop="true"
      :center-box="true"
      :can-move="false"
      :full="true"
      :intoTrue="true"
    />
    <div style="margin-bottom: 16px" />
    <!--图片协同编辑操作-->
    <div class="image-edit-action" v-if="isTeamSpace">
      <a-space>
        <a-button v-if="editingUser" disabled>{{ editingUser?.userName }} 正在编辑</a-button>
        <a-button v-if="canEnterEdit" type="primary" ghost @click="enterEdit">进入编辑</a-button>
        <a-button v-if="canExitEdit" danger ghost @click="exitEdit">退出编辑</a-button>
      </a-space>
    </div>
    <!--图片操作-->
    <div class="image-cropper-action">
      <a-space>
        <a-button @click="rotateLeft" :disabled="!canEditPicture">向左旋转</a-button>
        <a-button @click="rotateRight" :disabled="!canEditPicture">向右旋转</a-button>
        <a-button @click="changeScale(1)" :disabled="!canEditPicture">放大</a-button>
        <a-button @click="changeScale(-1)" :disabled="!canEditPicture">缩小</a-button>
        <a-button type="primary" :loading="loading" :disabled="!canEditPicture" @click="handleConfirm">确认</a-button>
      </a-space>
    </div>
  </a-modal>
</template>
<script lang="ts" setup>
import { computed, onUnmounted, ref, watchEffect } from 'vue'
import { uploadPictureUsingPost } from '@/api/pictureController.ts'
import { message } from 'ant-design-vue'
import { useLoginUserStore } from '@/stores/useLoginUserStore.ts'
import PictureEditWebSocket from '@/utils/pictureEditWebSocket.ts'
import { PICTURE_EDIT_ACTION_ENUM, PICTURE_EDIT_MESSAGE_TYPE_ENUM } from '@/constants/picture.ts'
import { SPACE_TYPE_ENUM } from '@/constants/space.ts'

interface Props {
  imageUrl?: string
  picture?: API.PictureVO
  spaceId?: number
  space?: API.SpaceVO
  onSuccess?: (newPicture: API.PictureVO) => void
  onConfirmSuccess?: () => void
}

// 是否为团队空间
const isTeamSpace = computed(() => {
  return props.space?.spaceType === SPACE_TYPE_ENUM.TEAM
})


const props = defineProps<Props>()

const visible = ref(false)

const openModal = () => {
  visible.value = true
}

// 暴露函数给父组件
defineExpose({
  openModal,
})

// 获取图片裁切器的引用
const cropperRef = ref()

const handleConfirm = () => {
  cropperRef.value.getCropBlob((blob: Blob) => {
    // blob 为裁切好的文件
    const fileName = (props.picture?.name || 'image') + '.png'
    const file = new File([blob], fileName, { type: blob.type })
    // 上传图片
    handleUpload({ file })
  })
}

const loading = ref(false)

/**
 * 上传图片
 * @param file
 */
const handleUpload = async ({ file }: any) => {
  loading.value = true
  try {
    const params: API.PictureUploadRequest = props.picture ? { id: props.picture.id } : {}
    params.spaceId = props.spaceId
    const res = await uploadPictureUsingPost(params, {}, file)
    if (res.data.code === 0 && res.data.data) {
      message.success('上传成功')
      // 将上传成功的图片信息传递给父组件
      props.onSuccess?.(res.data.data)
      confirmExitEdit()
      closeModal()
    } else {
      message.error('上传失败' + res.data.message)
    }
  } catch (e) {
    console.error('上传失败' + e)
    message.error('上传失败' + e.message)
  }
  loading.value = false
}

// --------实时编辑--------
const loginUserStore = useLoginUserStore()
const loginUser = loginUserStore.loginUser

// 正在编辑的用户
const editingUser = ref<API.UserVO | null>()
// 当前用户是否可进入编辑
const canEnterEdit = computed(() => {
  return !editingUser.value
})
// 当前用户是否可退出编辑
const canExitEdit = computed(() => {
  return editingUser.value?.id === loginUser?.id
})
// 当前用户是否可编辑图片
const canEditPicture = computed(() => {
  // 个人空间下，只有登录用户可以编辑图片
  if (!isTeamSpace.value) {
    return true
  }
  // 团队空间下，只有创建者和管理员可以编辑图片
  return editingUser.value?.id === loginUser?.id
})

// 图片协同编辑 WebSocket
let websocket: PictureEditWebSocket | null;
// 初始化 WebSocket 连接，绑定监听事件
const initWebSocket = () => {
  const pictureId = props.picture?.id
  if (!pictureId || !visible.value) {
    return
  }
  // 防止之前连接未释放
  if (websocket) {
    websocket.disconnect()
  }

  // 创建 WebSocket 实例
  websocket = new PictureEditWebSocket(pictureId)
  // 建立连接
  websocket.connect()

  // 监听消息
  websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.INFO, (msg) => {
    console.log('收到通知消息', msg)
    if (msg.editUser) {
      editingUser.value = msg?.editUser
    }
    message.info(msg.message)
  })

  websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.ERROR, (msg) => {
    console.log('收到错误通知', msg)
    message.info(msg.message)
  })

  websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.ENTER_EDIT, (msg) => {
    console.log('收到进入编辑状态通知', msg)
    message.info(msg.message)
    editingUser.value = msg.user
  })

  websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.EXIT_EDIT, (msg) => {
    console.log('收到退出编辑状态通知', msg)
    message.info(msg.message)
    editingUser.value = undefined
  })

  websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.CONFIRM_EXIT_EDIT, (msg) => {
    console.log('收到已提交退出编辑状态通知', msg)
    message.info(msg.message)
    props.onConfirmSuccess?.()
    closeModal()
  })

  // 监听编辑操作消息
  websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.EDIT_ACTION, (msg) => {
    console.log('收到编辑操作消息：', msg)
    message.info(msg.message)
    switch (msg.editAction) {
      case PICTURE_EDIT_ACTION_ENUM.ROTATE_LEFT:
        cropperRef.value.rotateLeft()
        break
      case PICTURE_EDIT_ACTION_ENUM.ROTATE_RIGHT:
        cropperRef.value.rotateRight()
        break
      case PICTURE_EDIT_ACTION_ENUM.ZOOM_IN:
        cropperRef.value.changeScale(1)
        break
      case PICTURE_EDIT_ACTION_ENUM.ZOOM_OUT:
        cropperRef.value.changeScale(-1)
        break
    }
})}

// 监听属性和 visible 变化，初始化 WebSocket 连接
watchEffect(() => {
  // 只要团队空间才初始化 WebSocket 连接
  if (isTeamSpace.value) {
    initWebSocket()
  }
})

onUnmounted(() => {
  // 页面卸载时，断开 WebSocket 连接
  if (websocket) {
    websocket.disconnect()
  }
  editingUser.value = undefined
})

// 进入编辑状态
const enterEdit = () => {
  if (websocket) {
    websocket.sendMessage({
      type: PICTURE_EDIT_MESSAGE_TYPE_ENUM.ENTER_EDIT
    })
  }

}

// 退出编辑状态
const exitEdit = () => {
  if (websocket) {
    websocket.sendMessage({
      type: PICTURE_EDIT_MESSAGE_TYPE_ENUM.EXIT_EDIT
    })
  }
}

// 提交图片后通知其他编辑用户退出编辑状态
const confirmExitEdit = () => {
  if (websocket) {
    websocket.sendMessage({
      type: PICTURE_EDIT_MESSAGE_TYPE_ENUM.CONFIRM_EXIT_EDIT
    })
  }
}

// 发送编辑操作
const editAction = (action: string) => {
  if (websocket) {
    websocket.sendMessage({
      type: PICTURE_EDIT_MESSAGE_TYPE_ENUM.EDIT_ACTION,
      editAction: action
    })
  }
}

const closeModal = () => {
  visible.value = false
  if (websocket) {
    websocket.disconnect()
  }
  editingUser.value = undefined
}

// 缩放比例
const changeScale = (num: number) => {
  cropperRef.value.changeScale(num)
  if (num > 0) {
    editAction(PICTURE_EDIT_ACTION_ENUM.ZOOM_IN)
  } else {
    editAction(PICTURE_EDIT_ACTION_ENUM.ZOOM_OUT)
  }
}

// 向左旋转
const rotateLeft = () => {
  cropperRef.value.rotateLeft()
  editAction(PICTURE_EDIT_ACTION_ENUM.ROTATE_LEFT)
}

// 向右旋转
const rotateRight = () => {
  cropperRef.value.rotateRight()
  editAction(PICTURE_EDIT_ACTION_ENUM.ROTATE_RIGHT)
}

</script>
<style>
.image-cropper {
  text-align: center;
}
.image-cropper .vue-cropper {
  height: 400px !important;
}
</style>
